#pragma once

#include "stdint.h"
/**********在这里定义一些常量**********/
const int TICKS_INTERVAL = 1;  // 轮询间隔，单位ms
const int DEBOUNCE_TICKS = 5;  // 消抖时间，单位*TICKS_INTERVAL
const int SHORT_INTERVAL = 250;  // 短按时间，单位ms,双击时间间隔小于这个的一半
const int LONG_INTERVAL = 1000;  // 长按时间，单位ms

class Button {
 public:
  enum State {
    None_Press = 0,  // 无按键
    First_Press,     // 第一次按下
    Press_Check,     // 连击检测
    Single_Check,    // 单击
    Double_Check,    // 双击
    Long_Press,      // 长按
  };

 private:
  enum PressEvent {
    NONE_PRESS = 0,   // 无按键
    PRESS_SINGLE,     // 单击
    PRESS_DOUBLE,     // 双击
    PRESS_LONG_START,       // 长按开始,只触发一次
    PRESS_LONG_HOLD,        // 长按保持，每隔一段时间触发一次
    number_of_event,  // 事件数量
  };
  const int buttonId;  // 按键编号
  State state;         // 按键状态
  PressEvent event;    // 按键事件
  typedef void (*callback_t)();
  callback_t callback[number_of_event-1];    // 回调函数指针
   bool ( *const read_Pin)();  // 读取按键电平函数
  const bool active_level;   // 有效电平
  bool pin;                  // 现在电平
  uint8_t debounce_cnt;      // 消抖计数器
    uint16_t ticksTime;//记录按下/松开的时间
    uint16_t getInterval();
 public:
  bool register_callback(const callback_t callback, const PressEvent event);
  Button(const int buttonId, bool (*const read_Pin)(), const bool active_level)
      : buttonId(buttonId),
        read_Pin(read_Pin),
        active_level(active_level),
        state(None_Press),
        event(NONE_PRESS),
        debounce_cnt(0) {
    pin = !active_level;
    state = None_Press;
    event = NONE_PRESS;
    debounce_cnt = 0;
    ticksTime = 0;
    for (int i = 0; i < 3; i++) {
      callback[i] = nullptr;
    }
  };
  void tick_handler();  // 定时扫描函数
};
void LOG(const char* str);
